﻿package com.hatic.login;


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;


/**
 * 
 * 自动根据单点登录系统的信息设置本系统的用户信息 <br/>
 * 在 loginByUsername方法中实现系统登陆。
 * 
 */
public class AutoSetUserAdapterFilter implements Filter {

	/**
	 * Represents the constant for where the assertion will be located in
	 * memory.
	 */
	private static final String CONST_CAS_ASSERTION = "_const_cas_assertion_";

	private static final String CAS_LOGIN = "_cas_login_";

	Map info = new HashMap();

	/**
	 * Default constructor.
	 */
	public AutoSetUserAdapterFilter() {
	}

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
	}

	/**
	 * 
	 * 过滤逻辑：首先判断单点登录的账户是否已经存在本系统中， 如果不存在使用用户查询接口查询出用户对象并设置在Session中
	 * 
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpSession session = httpRequest.getSession();
		
		// 用户已登录
		if (session.getAttribute(CAS_LOGIN) != null) {
			chain.doFilter(request, response);
			return;
		}
		// _const_cas_assertion_是CAS中存放登录用户名的session标志
		Object object = session.getAttribute(CONST_CAS_ASSERTION);
		String loginName = "";

		if (object != null) {
			Assertion assertion = (Assertion) object;
			loginName = assertion.getPrincipal().getName();// 通过该方法可得到用户登录帐号
			// 获取更多的用户信息
			AttributePrincipal principal = (AttributePrincipal) httpRequest
					.getUserPrincipal();
			if (null == principal) {
				chain.doFilter(request, response);
				return;
			}
			
			Map attributes = principal.getAttributes();
			String loginId = "";
				
			Object valuesObject = attributes.get("attribute");
			if (null != valuesObject) {
				String values = valuesObject.toString().replaceAll("\n", ",")
						.replaceAll(" ", "");
				String[] value = values.substring(1, values.length() - 1)
						.split(",");
				info.put(value[0], value[1]);// key：userId value：用户ID
				info.put(value[3], value[4]);// key：userAccount value：用户帐号
				// 可以根据自身用户对应关系，使用相应的值进行登录操作
			} else {
				chain.doFilter(request, response);
				return;
			}

			// 将用户信息封装到Map中，其中具体的key值，参见cas server端的配置，具体请联系集成项目组

			// assertion.getPrincipal() 获取cas传过来的额外属性
			System.out.println("map:" + assertion.getPrincipal());

			// loginName 为传过来的用户名
			System.out.println("loginName:" + loginName);

			// 系统登陆验证
			loginByUsername(httpRequest,loginName);
		} else {
			//add by tony.tan 2012-07-18
			String casUserId = "", casUserCode = "";
			Map<String,String> mpUser = (Map<String,String>) session.getAttribute("curruser");
			if (mpUser != null && !mpUser.isEmpty()) {
				String userId = mpUser.get("user_id");
				Map<String,String> mpCasUser = PmLoginUtil.queryCasUser(userId);
				if (!mpCasUser.isEmpty()) {
					casUserId = mpCasUser.get("cas_user_id");
					casUserCode = mpCasUser.get("cas_user_code");
				}
			}
			//------------------------------
			
			org.jasig.cas.client.validation.Assertion assertion;
			Map attributes = new HashMap();
			attributes.put("value", casUserId);
			assertion = new org.jasig.cas.client.validation.AssertionImpl(
					new org.jasig.cas.client.authentication.AttributePrincipalImpl(
							casUserCode, attributes));
			session.setAttribute(CONST_CAS_ASSERTION, assertion);
		}

		chain.doFilter(request, response);
	}

	/**
	 * 使用用户名称登陆系统
	 * 
	 * @param username
	 * @return
	 */
	private boolean loginByUsername(HttpServletRequest request,String username) {
		HttpSession session = request.getSession();
		/**
		 * 如果_cas_login_不存在表示系统未登陆过
		 */		
		if (session.getAttribute(CAS_LOGIN) == null) {
			// 添加实现用户登陆方法，可以根据自身用户对应关系，从info取得相应的值进行登录操作
			// 登陆失败return false;
			//add by tony.tan 2012-07-18
			Map<String,String> mpUser = (Map<String,String>) session.getAttribute("curruser");
			if (mpUser == null || mpUser.isEmpty()) {
				PmLoginBO loginBO = new PmLoginBO();
				
				String userCode = PmLoginUtil.queryUserCode((String)info.get("userId"));
				if (userCode == null || userCode.length() == 0) {
					System.out.println(".............集成用户【"+ (String)info.get("userAccount") +"】内部id【"+(String)info.get("userId")+"】在本系统中没有对应的用户信息！");
					return false;
				}
				mpUser = loginBO.casLogin(userCode, "", "1", "");
				session.setAttribute("curruser", mpUser);
			}
			//------------------------------------------------------------

			saveUserToSession(session, username);
			return true;
		}
		return false;
	}

	/**
	 * 
	 * 将用户信息存储本地session
	 * 
	 * @param session
	 * @param user
	 */
	private void saveUserToSession(HttpSession session, String user) {
		session.setAttribute(CAS_LOGIN, user);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
	}

}